// For debug output to console
Canvas.debug = true;

function Canvas() {
	this.dprint("CanvasV2 Constructor");
	
	this.isMakingShape = false;
	
	var baseObj = new CanvasObject();
	baseObj.setAttribute("width",500);
	baseObj.setAttribute("height", 500);
	baseObj.setAttribute("x", 0);
	baseObj.setAttribute("y", 0);
	
	baseObj.setAttribute("background", "white");
	baseObj.setAttribute("opacity", "1.0");
	//baseObj.setCss("opacity", "1.0");
	
	this.rootObject = baseObj;
	this.setBaseObject(baseObj);
	
	this.selectedObject = null;
	
	this.selectedObjects = [];
	
	this.initMouseControls();
	this.initKeyboardControls();
}

Canvas.className = "Canvas";

// Singleton instance
Canvas._theCanvas = null;
function theCanvas() { return Canvas._theCanvas; }
//Canvas.theCanvas = function() { return _theCanvas; };


Canvas.attributes = new Array(
	//{name: "id", value: "canvas"},
	{name: "width", cssName: "width", value: 500},
	{name: "height", cssName: "height", value: 500},
	{name: "background", cssName: "background", value: "transparent"},
	{name: "backgroundImage", cssName: "background-image", value: ""}
);

Canvas.prototype.initDomElem = function() {
	
};

Canvas.prototype.initMouseControls = function() {
	var obj = this;
	$("#canvas_container").click(function() {
		//obj.getBaseObject().setSelectedObject(null);
		obj.baseObject.setSelectedObjects(null);
	});
}

Canvas.prototype.initKeyboardControls = function() {
	var obj = this;
	$(document).keydown(function(e) {
		//obj.dprint("keydown");
		obj.dprint(e.keyCode);
		
		if (e.keyCode == 38) { // up key

			if (e.ctrlKey) {
				if (obj.baseObject.parent != null) {
					obj.dprint("Go up");
					obj.setBaseObject(obj.baseObject.parent);
				}
			} else {
				obj.dprint("nudge up");
				if (obj.baseObject.selectedObjects != null) {
					for (var i in obj.baseObject.selectedObjects) {
						var o = obj.baseObject.selectedObjects[i];
						if (e.shiftKey) {
							o.setAttribute("y", o.y - 10);						
						} else {
							o.setAttribute("y", o.y - 1);
						}
					}
				}
			}
		} else if (e.keyCode == 40) { // down key
			if (obj.getSelectedObject() != null) {
				
				if (e.ctrlKey) {
					if (obj.baseObject.selectedObjects != null &&
						obj.baseObject.selectedObjects.length > 0) {
						obj.dprint("Go down");
						obj.setBaseObject(obj.baseObject.selectedObjects[0]);
					}
				} else {
					if (obj.baseObject.selectedObjects != null) {
						for (var i in obj.baseObject.selectedObjects) {
							var o = obj.baseObject.selectedObjects[i];
							if (e.shiftKey) {
								o.setAttribute("y", o.y + 10);						
							} else {
								o.setAttribute("y", o.y + 1);
							}
						}
					}
				}
			}
		} else if (e.keyCode == 37) { // left
			if (obj.getSelectedObject() != null) {
				
				if (e.ctrlKey) {

				} else {
					if (obj.baseObject.selectedObjects != null) {
						for (var i in obj.baseObject.selectedObjects) {
							var o = obj.baseObject.selectedObjects[i];
							if (e.shiftKey) {
								o.setAttribute("x", o.x - 10);						
							} else {
								o.setAttribute("x", o.x - 1);
							}
						}
					}
				}
			}
		} else if (e.keyCode == 39) { // right
			if (obj.getSelectedObject() != null) {
				
				if (e.ctrlKey) {

				} else {
					if (obj.baseObject.selectedObjects != null) {
						for (var i in obj.baseObject.selectedObjects) {
							var o = obj.baseObject.selectedObjects[i];
							if (e.shiftKey) {
								o.setAttribute("x", o.x + 10);						
							} else {
								o.setAttribute("x", o.x + 1);
							}
						}
					}
				}
			}
		
		}else if (e.keyCode == 46) {
			if (obj.baseObject.selectedObjects != null) {
				for (var i in obj.baseObject.selectedObjects) {
					var o = obj.baseObject.selectedObjects[i];
					obj.baseObject.removeObject(obj.baseObject.selectedObjects[i]);
					theControlPanel().fullRefresh();
				}
			}
			//obj.baseObject.removeObject(obj.baseObject.getSelectedObject());
		} /* else if (e.keyCode == 61) { // Create new object
			theCanvas().beginCreatingShape();
		} else if (e.keyCode == 49) {
			theCanvas().beginCreatingShape("input type='text'");
		} */
	});
};

Canvas.prototype.dumpHtml = function() {
	this.dprint("STUB: dumpHtml");
	
	
	
	// pre tag keeps string properly formatted
	// return "<pre>" + escapeHtml(this.dumpCss()) + escapeHtml(this.dumpRawHtml()) + "</pre>";
};

Canvas.prototype.setBaseObject = function(baseObj) {

	// Reset cur doc name so don't save sub layer as super layer
	curDocName = "";


	this.dprint("Set base object: " + baseObj.id);

	if (this.baseObject != null && this.baseObject != undefined) {
	
		this.baseObject.domElem.unbind("click");
	
		this.baseObject.domElem.toggleClass("canvas");
		this.baseObject.domElem.toggleClass("object");
		
		// This object is no longer our canvas
		for (var i in this.baseObject.children) {
			this.baseObject.children[i].disableClickHandlers();
		 }
		
		if (this.baseObject.parent != null) {
			this.baseObject.parent.domElem.append(this.baseObject.domElem);
		}
		
		// set domElem's top and left values back to their actual values
		this.baseObject.domElem.css("top", this.baseObject.y + "px");
		this.baseObject.domElem.css("left", this.baseObject.x + "px");
		
		this.baseObject.domElem.selectable('destroy');
	}

	
	this.baseObject = baseObj;
	
	/*
	var topVal = ($("#canvas_container").height() - this.baseObject.height) / 2;
	var leftVal = ($("#canvas_container").width() - this.baseObject.width) / 2;
	
	this.dprint("container: " + $("#canvas_container").height() );
	this.dprint("canvas   : " + this.baseObject.height );
	this.dprint("topVal   : " + topVal);
	
	this.dprint("container: " + $("#canvas_container").width() );
	this.dprint("canvas   : " + this.baseObject.width );
	this.dprint("leftVal   : " + leftVal);
	
	this.baseObject.domElem.css("top", topVal+"px");
	this.baseObject.domElem.css("left", leftVal+"px");
	*/
	$("#canvas_container").empty();
	$("#canvas_container").append(this.baseObject.domElem);
	
	
	this.dprint("setting click handler");
	var obj = this;
	baseObj.domElem.click(function() {
		obj.dprint("click");
		
		//obj.baseObject.setSelectedObject(null);
		obj.baseObject.setSelectedObjects([]);
	});

	baseObj.domElem.toggleClass("canvas");
	baseObj.domElem.toggleClass("object");
	for (var i in this.baseObject.children) {
		this.baseObject.children[i].enableClickHandlers();
	}
	
	baseObj.domElem.selectable({
		filter: ".object",
		start: function(event, ui) {
			//alert("boo");
		},
		stop: function(event, ui) {
		
		},
		selected: function(event, ui) {
			obj.dprint("selected: " + event.target.id);
			var selectedItem = obj.baseObject.children[event.target.id];
			
			if (event.shiftKey) {
				var objs = baseObj.selectedObjects;		
			} else {
				var objs = [];
			}
			
			baseObj.selectedObjects = [];
			$(".object.ui-selected").each(function() {
				var o = obj.baseObject.children[$(this).attr("id")];
				//if(!o.isSelected) {
					objs.push(o);
				//}
				//objs.push(obj.baseObject.children[$(this).attr("id")]);
				//baseObj.selectedObjects.push(obj.baseObject.children[$(this).attr("id")]);
				//obj.baseObject.children[$(this).attr("id")].setIsSelected(true);
			});
			baseObj.setSelectedObjects(objs);
			
			$(".object:not(.ui-selected)").each(function() {
				//obj.baseObject.children[$(this).attr("id")].setIsSelected(false);
			});
			
		},
		unselected: function(event, ui) {
			obj.dprint("selected: " + event.target.id);
			var selectedItem = obj.baseObject.children[event.target.id];

			if (event.shiftKey) {
				var objs = baseObj.selectedObjects;		
			} else {
				var objs = [];
			}

			$(".object.ui-selected").each(function() {
				var o = obj.baseObject.children[$(this).attr("id")];

					objs.push(o);
				
				//baseObj.selectedObjects.push(obj.baseObject.children[$(this).attr("id")]);
				//obj.baseObject.children[$(this).attr("id")].setIsSelected(true);
			});
			baseObj.setSelectedObjects(objs);
			$(".object:not(.ui-selected)").each(function() {
				//obj.baseObject.children[$(this).attr("id")].setIsSelected(false);
			});
			
		}
	});
	
	this.baseObjectChanged();
	this.selectedChanged();
}

Canvas.prototype.getBaseObject = function(baseObj) {
	return this.baseObject;
}

Canvas.prototype.beginCreatingShape = function(type) {
	this.dprint("beginCreatingShape: " + type);
	this.domElem.toggleClass("creating", true);
	this.isMakingShape = true;
	
	if (type == undefined) {
		this.isMakingType = "div";
	} else  {
		this.isMakingType = type;
	}
};

Canvas.prototype.endCreatingShape = function() {
	this.dprint("endCreatingShape");

	this.isMakingShape = false;
	this.domElem.toggleClass("creating", false);
	//this.addObject(this.shapeBeingMade);
	this.shapeBeingMade = undefined;
	this.isMakingType = undefined;
	this.anchorPoint = undefined;
};

Canvas.prototype.getSelectedObject = function() {
	return this.baseObject.getSelectedObject();
};

//
// Align / Distribute Functions
//

Canvas.prototype.alignLeft = function() { 
	this.dprint("Align Left");

	var minX = 10000;
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		if (o.x < minX) {
			minX = o.x;
		}
	}
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		o.setAttribute("x", minX);
	}

};
Canvas.prototype.alignRight = function() {
	this.dprint("Align Right");

	var maxX = -10000;
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		if (o.x > maxX) {
			maxX = o.x+o.width;
		}
	}
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		o.setAttribute("x", maxX - o.width);
	}


};
Canvas.prototype.alignCenter = function() {
	this.dprint("Align Center");

	var centerX = 0;
	var numObjects = 0;
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		centerX += (o.x + o.width/2);
		numObjects++;
	}
	centerX /= numObjects;
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		o.setAttribute("x", centerX - o.width/2);
	}
};
Canvas.prototype.alignTop = function() {
	this.dprint("Align Top");

	var minY = 10000;
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		if (o.y < minY) {
			minY = o.y;
		}
	}
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		o.setAttribute("y", minY);
	}
};
Canvas.prototype.alignMiddle = function() {
	this.dprint("Align Middle");

	var middleY = 0;
	var numObjects = 0;
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		middleY += (o.y + o.height/2);
		numObjects++;
	}
	middleY /= numObjects;
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		o.setAttribute("y", middleY - o.height/2);
	}
};
Canvas.prototype.alignBottom = function() {
	this.dprint("Align Bottom");

	var maxY = -10000;
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		if (o.y > maxY) {
			maxY = o.y+o.height;
		}
	}
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		o.setAttribute("y", maxY - o.height);
	}
};

Canvas.prototype.distributeHorizontalCenters = function() {
	var maxCenter = -10000;
	var minCenter = 10000;
	
	var ordering = [];
	var numElements = 0;
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		var oCenter = o.x + (o.width/2);
		
		if (oCenter > maxCenter) {
			maxCenter = oCenter;
		}
		if (oCenter < minCenter) {
			minCenter = oCenter;
		}
		
		// insert object in sorted order into order array
		var wasInserted = false;
		for (var i=0; i<numElements; i++) {
			
			var otherCenter = ordering[i].x + (ordering[i].width / 2);
			if (oCenter < otherCenter) {
				//this.dprint(o.id + " inserted at " + i + " othercenter: " + otherCenter);
				ordering.splice(i, 0, o);
				wasInserted = true;
				break;
			}
			
		}
		
		if (!wasInserted) {
			//this.dprint(o.id + " inserted at the end");
			ordering.push(o);
		}	
		
		numElements++;
	}
	
	// Now go through and position elements
	var range = maxCenter - minCenter;
	var betweenDistance = range / (numElements - 1);
	
	for (var i=0; i<numElements; i++) {
		var o = ordering[i];
		o.setAttribute("x", minCenter + (i * betweenDistance) - (o.width / 2));
	}

	
//	this.dprint("ordering: ");
//	for (var i=0; i<numElements; i++) {
//		this.dprint("  " + ordering[i].id);
//	}
//	
//	this.dprint("between dist: " + betweenDistance);
//	this.dprint("range: " + range);
//	this.dprint("minCenter: " + minCenter);
//	this.dprint("maxCenter: " + maxCenter);
	
};

Canvas.prototype.distributeVerticalCenters = function() {
	var maxCenter = -10000;
	var minCenter = 10000;
	
	var ordering = [];
	var numElements = 0;
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		var oCenter = o.y + (o.height/2);
		
		if (oCenter > maxCenter) {
			maxCenter = oCenter;
		}
		if (oCenter < minCenter) {
			minCenter = oCenter;
		}
		
		// insert object in sorted order into order array
		var wasInserted = false;
		for (var i=0; i<numElements; i++) {
			
			var otherCenter = ordering[i].y + (ordering[i].height / 2);
			if (oCenter < otherCenter) {
				//this.dprint(o.id + " inserted at " + i + " othercenter: " + otherCenter);
				ordering.splice(i, 0, o);
				wasInserted = true;
				break;
			}
			
		}
		
		if (!wasInserted) {
			//this.dprint(o.id + " inserted at the end");
			ordering.push(o);
		}	
		
		numElements++;
	}
	
	// Now go through and position elements
	var range = maxCenter - minCenter;
	var betweenDistance = range / (numElements - 1);
	
	for (var i=0; i<numElements; i++) {
		var o = ordering[i];
		o.setAttribute("y", minCenter + (i * betweenDistance) - (o.height / 2));
	}

};

Canvas.prototype.distributeHorizontalSpacebetween = function() {

	var minX = 10000;
	var maxX = -10000;
	
	var order = [];
	var numElements = 0;
	
	var takenSpace = 0;
	var freeSpace = 0;
	var distBetweenEdges = 0;
	
	var ordering = [];
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		if (o.x < minX) {
			minX = o.x;
		}
		if (o.x + o.width > maxX) {
			maxX = o.x + o.width;
		}
		
		// insert object in sorted order into order array
		var wasInserted = false;
		for (var i=0; i<numElements; i++) {
			
			if (o.x < ordering[i].x) {
				//this.dprint(o.id + " inserted at " + i + " othercenter: " + otherCenter);
				ordering.splice(i, 0, o);
				wasInserted = true;
				break;
			}
			
		}
		
		if (!wasInserted) {
			//this.dprint(o.id + " inserted at the end");
			ordering.push(o);
		}	
		
		takenSpace += o.width;
		numElements++;
	}
	
	freeSpace = (maxX - minX) - takenSpace;
	distBetweenEdges = freeSpace / (numElements - 1);
	
	var curX = minX;
	for (var i=0; i<numElements; i++) {
		var o = ordering[i];
		o.setAttribute("x", curX);
		curX += o.width + distBetweenEdges;
	}

};

Canvas.prototype.distributeVerticalSpacebetween = function() {

	var minY = 10000;
	var maxY = -10000;
	
	var order = [];
	var numElements = 0;
	
	var takenSpace = 0;
	var freeSpace = 0;
	var distBetweenEdges = 0;
	
	var ordering = [];
	
	for (var obj_id in this.baseObject.selectedObjects) {
		var o = this.baseObject.selectedObjects[obj_id];
		
		if (o.y < minY) {
			minY = o.y;
		}
		if (o.y + o.height > maxY) {
			maxY = o.y + o.height;
		}
		
		// insert object in sorted order into order array
		var wasInserted = false;
		for (var i=0; i<numElements; i++) {
			
			if (o.y < ordering[i].y) {
				//this.dprint(o.id + " inserted at " + i + " othercenter: " + otherCenter);
				ordering.splice(i, 0, o);
				wasInserted = true;
				break;
			}
			
		}
		
		if (!wasInserted) {
			//this.dprint(o.id + " inserted at the end");
			ordering.push(o);
		}	
		
		takenSpace += o.height;
		numElements++;
	}
	
	freeSpace = (maxY - minY) - takenSpace;
	distBetweenEdges = freeSpace / (numElements - 1);
	
	var curY = minY;
	for (var i=0; i<numElements; i++) {
		var o = ordering[i];
		o.setAttribute("y", curY);
		curY += o.height + distBetweenEdges;
	}

};

/*
Canvas.prototype.setSelectedObjects = function(objects) {

	var selectedObjects = this.baseObject.selectedObjects;
	if (selectedObjects != null) {
	
		for (var i=0; i<selectedObjects.length; i++) {
			var o = selectedObjects[i];
			o.setIsSelected(false);
		}
		
		this.baseObject.selectedObjects = [];
		
		if (objects != null && objects.length > 0) {
			for (var i=0; i<objects.length; i++) {
				this.baseObject.selectedObjects.push(objects[i]);
				objects[i].setIsSelected(true);
			}
			$("#object_control_container").show();
		} else {
			$("#object_control_container").hide();
		}	

	}
};
*/

/*
Canvas.prototype.setSelectedObject = function(o) {
	
	this.dprint("setSelectedObject: " + o);
	
	if (this.selectedObject != null) {
		this.dprint("selectedObject was null before");	
		this.selectedObject.setIsSelected(false);
		this.selectedObject = null;
	}
	
	if (o == null) {
		this.dprint("set selected to null");
	} else {
	
		var obj = this.objects[o.id];
		if (obj == this.selectedObject) {
			//this.dprint("object already selected");
			//return;
		}
		
		//this.dprint("setSelectedObject: " + obj);
		this.selectedObject = obj;
		obj.setIsSelected(true);
	
	}
	
	this.selectedChanged();
};
*/

Canvas.prototype.selectedChanged = function() {
	theControlPanel().fullRefresh();
}

Canvas.prototype.valueChanged = function() {
	this.dprint("valueChanged");
	
	// Handles case where is called from constructor
	if (theCanvas() != null) {
		theControlPanel().fullRefresh();
		//updateControlPanel();
	}
};

Canvas.prototype.baseObjectChanged = function() {
	theControlPanel().updateNavMap();
	theControlPanel().fullRefresh();
}

// Debug output to console
Canvas.prototype.dprint = function(str) {
	if (Canvas.debug) {
		cprint(Canvas.className + ": " + str, "#00ff00");
	}
};

